import json
import sys
import time
import traceback
from functools import partial

import requests
from PySide2.QtWidgets import QMainWindow, QApplication, QLineEdit, QLabel, QSlider

from client.communicator import CommunicatorObj
from client.ui.ui_main import Ui_MainWindow


class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self):
        super().__init__()
        # 设置界面为我们生成的界面
        self.setupUi(self)
        # 初始化界面
        self.setupWidgets()
        # self.input_host.setText('192.168.2.117:6666')
        self.__host = ''
        self.communicator = None
        self.input_host.setText('192.168.2.117:6666')

    def setupWidgets(self):
        self.input_host.textChanged.connect(self.on_input_host_text_changed)
        self.button_connect.clicked.connect(self.connect_arm)
        self.button_reset_arm.clicked.connect(self.reset_arm)
        self.button_start_study.clicked.connect(self.start_study)
        self.button_finish_study.clicked.connect(self.finish_study)
        self.button_get_position.clicked.connect(self.get_position)
        self.button_move.clicked.connect(self.move_arm)
        self.slider_1.setMaximum(180)
        self.slider_2.setMaximum(180)
        self.slider_3.setMaximum(180)
        self.slider_4.setMaximum(180)
        self.slider_5.setMaximum(270)
        self.slider_6.setMaximum(180)
        self.slider_7.setMaximum(180)
        self.slider_1.valueChanged.connect(partial(self.on_slider_value_changed, 1))
        self.slider_2.valueChanged.connect(partial(self.on_slider_value_changed, 2))
        self.slider_3.valueChanged.connect(partial(self.on_slider_value_changed, 3))
        self.slider_4.valueChanged.connect(partial(self.on_slider_value_changed, 4))
        self.slider_5.valueChanged.connect(partial(self.on_slider_value_changed, 5))
        self.slider_6.valueChanged.connect(partial(self.on_slider_value_changed, 6))
        self.slider_7.valueChanged.connect(partial(self.on_slider_value_changed, 7))
        self.slider_r.setMaximum(255)
        self.slider_g.setMaximum(255)
        self.slider_b.setMaximum(255)
        self.slider_r.valueChanged.connect(partial(self.on_rgb_value_changed, 'r'))
        self.slider_g.valueChanged.connect(partial(self.on_rgb_value_changed, 'g'))
        self.slider_b.valueChanged.connect(partial(self.on_rgb_value_changed, 'b'))
        self.input_r.setText('0')
        self.input_g.setText('0')
        self.input_b.setText('0')
        self.input_r.textChanged.connect(partial(self.on_rgb_value_changed, 'r'))
        self.input_g.textChanged.connect(partial(self.on_rgb_value_changed, 'g'))
        self.input_b.textChanged.connect(partial(self.on_rgb_value_changed, 'b'))
        self.button_run_combo.clicked.connect(self.on_button_run_combo_clicked)
        self.button_clear_combo.clicked.connect(self.textEdit.clear)
        self.button_on.clicked.connect(self.on_button_on_clicked)
        self.button_off.clicked.connect(self.on_button_off_clicked)
        self.input_bcm_code.setText('21')
        self.input_clockwise_pin.setText('20')
        self.input_anticlockwise_pin.setText('21')
        self.button_motor_clockwise.clicked.connect(self.on_button_motor_clockwise_clicked)
        self.button_motor_anticlockwise.clicked.connect(self.on_button_motor_anticlockwise_clicked)
        self.button_motor_close.clicked.connect(self.on_button_motor_close_clicked)
        self.input_input_pin.setText('16')
        self.input_output_pin.setText('20')
        self.button_read_input.clicked.connect(self.on_button_read_input_clicked)
        self.input_enable_pin.setText('17')
        self.input_direction_pin.setText('27')
        self.input_step_pin.setText('22')
        self.button_step_motor_clockwise.clicked.connect(self.on_button_step_motor_clockwise_clicked)
        self.button_step_motor_anticlockwise.clicked.connect(self.on_button_step_motor_anticlockwise_clicked)

    def connect_arm(self):
        self.__host = self.input_host.text()
        self.communicator = CommunicatorObj(self.__host)
        self.get_position()

    def on_button_run_combo_clicked(self):
        list_combo = self.textEdit.toPlainText().split('\n')
        print(list_combo)
        for combo in list_combo:
            combo = eval(combo)
            print(combo)
            self.communicator.move_all(combo)
            time.sleep(1)

    def on_rgb_value_changed(self, pos, value):
        self.findChild(QSlider, 'slider_' + str(pos)).setValue(int(value))
        self.findChild(QLineEdit, 'input_' + str(pos)).setText(str(value))
        self.set_rgb()

    def on_input_host_text_changed(self, text):
        self.__host = text
        self.communicator = CommunicatorObj(self.__host)

    def on_slider_value_changed(self, pos, value):
        self.findChild(QLabel, 'label_slider_' + str(pos)).setText(str(value))
        if pos < 7:
            self.communicator.move_one(pos, value)
        else:
            self.communicator.set_pwm(self.input_pwm_id.text(), value)

    def reset_arm(self):
        self.communicator.reset_arm()

    def start_study(self):
        self.communicator.start_study()

    def finish_study(self):
        self.communicator.finish_study()

    def get_position(self):
        self.communicator.finish_study()
        pos = self.communicator.get_position()
        if pos:
            pos_list = json.loads(pos)
            for i in range(6):
                self.findChild(QLabel, 'label_slider_' + str(i + 1)).setText(str(pos_list[i]))
                if pos_list[i]:
                    self.findChild(QSlider, 'slider_' + str(i + 1)).setValue(int(pos_list[i]))
                else:
                    self.findChild(QSlider, 'slider_' + str(i + 1)).setValue(0)
            self.textEdit.append(pos)
            self.input_position.setText(pos.replace('[', '').replace(']', '').replace(' ', ''))

    def move_arm(self):
        position = self.input_position.text()
        pos_list = position.split(',')
        for i in range(6):
            self.findChild(QLabel, 'label_slider_' + str(i + 1)).setText(str(pos_list[i]))
            self.findChild(QSlider, 'slider_' + str(i + 1)).setValue(int(pos_list[i]))
        self.communicator.move_all(pos_list)

    def set_rgb(self):
        r = self.input_r.text()
        g = self.input_g.text()
        b = self.input_b.text()
        self.communicator.set_rgb(r, g, b)

    def on_button_on_clicked(self):
        bcm_code = self.input_bcm_code.text()
        value = '1'
        self.communicator.set_gpio(bcm_code, value)

    def on_button_off_clicked(self):
        bcm_code = self.input_bcm_code.text()
        value = '0'
        self.communicator.set_gpio(bcm_code, value)

    def on_button_motor_clockwise_clicked(self):
        clockwise_pin = self.input_clockwise_pin.text()
        anticlockwise_pin = self.input_anticlockwise_pin.text()
        self.communicator.set_gpio(anticlockwise_pin, 0)
        self.communicator.set_gpio(clockwise_pin, 1)

    def on_button_motor_anticlockwise_clicked(self):
        clockwise_pin = self.input_clockwise_pin.text()
        anticlockwise_pin = self.input_anticlockwise_pin.text()
        self.communicator.set_gpio(clockwise_pin, 0)
        self.communicator.set_gpio(anticlockwise_pin, 1)

    def on_button_motor_close_clicked(self):
        clockwise_pin = self.input_clockwise_pin.text()
        anticlockwise_pin = self.input_anticlockwise_pin.text()
        self.communicator.set_gpio(clockwise_pin, 0)
        self.communicator.set_gpio(anticlockwise_pin, 0)

    def on_button_read_input_clicked(self):
        input_pin = self.input_input_pin.text()
        output_pin = self.input_output_pin.text()
        self.communicator.read_input(input_pin, output_pin)

    def on_button_step_motor_clockwise_clicked(self):
        enable_pin = self.input_enable_pin.text()
        direction_pin = self.input_direction_pin.text()
        step_pin = self.input_step_pin.text()
        step = self.input_step.text()
        self.communicator.step_motor(enable_pin, direction_pin, step_pin, 1, 1, int(step))

    def on_button_step_motor_anticlockwise_clicked(self):
        enable_pin = self.input_enable_pin.text()
        direction_pin = self.input_direction_pin.text()
        step_pin = self.input_step_pin.text()
        step = self.input_step.text()
        self.communicator.step_motor(enable_pin, direction_pin, step_pin, 1, 2, int(step))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    # window.showMaximized()
    # 结束QApplication
    sys.exit(app.exec_())
